﻿#region Copyright
// Copyright (c) 2011-2012 RaisingForce Team (Alikin Sergey)
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using RaisingForce.Raise.Presentation.Localization;

namespace RaisingForce.Raise.Presentation.ViewModel.Specialized
{
    public class HardwareSelectorViewModel :
        ViewModelBase,
        ILocalizable
    {
        #region Constructors

        public HardwareSelectorViewModel()
            : base()
        {
            this.itemSelector.PropertyChanged += this.itemSelector_PropertyChanged;
            this.itemSelector.SelectionChanged += this.itemSelector_SelectionChanged;
        }

        #endregion

        #region Private Declarations

        private readonly ItemSelectorViewModel<IHardwareSettingViewModel> itemSelector =
            new ItemSelectorViewModel<IHardwareSettingViewModel>();

        private void OnSelectionChanged(bool localizationUpdateMode)
        {
            var item = this.itemSelector.SelectedItem;
            if (item != null)
            {
                this.HardwareName = item.Name;
                this.HardwareDescription = item.Description;
                if (!localizationUpdateMode)
                {
                    item.SetAsDefaultHardware();
                }
            }
            else
            {
                this.HardwareName = null;
                this.HardwareDescription = null;
            }
            if (!localizationUpdateMode)
            {
                this.OnHardwareSelectionChanged();
            }
        }

        /// <summary>
        /// Property name for ItemSelectorViewModel class.
        /// </summary>
        private const string propItemSelector_SelectedItem = "SelectedItem";

        /// <summary>
        /// Property name for ItemSelectorViewModel class.
        /// </summary>
        private const string propItemSelector_SelectedIndex = "SelectedIndex";

        /// <summary>
        /// Property name for ItemSelectorViewModel class.
        /// </summary>
        private const string propItemSelector_Items = "Items";

        /// <summary>
        /// Property name for ItemSelectorViewModel class.
        /// </summary>
        private const string propItemSelector_IsReadOnly = "IsReadOnly";

        private void itemSelector_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            string propertyName;
            switch (e.PropertyName)
            {
                case propItemSelector_SelectedIndex:
                    propertyName = "SelectedHardwareIndex";
                    break;
                case propItemSelector_SelectedItem:
                    propertyName = "SelectedHardware";
                    break;
                case propItemSelector_Items:
                    propertyName = "HardwareItems";
                    break;
                case propItemSelector_IsReadOnly:
                    propertyName = "IsEnabled";
                    break;
                default:
                    propertyName = null;
                    break;
            }
            if (propertyName != null)
            {
                this.OnPropertyChanged(propertyName);
            }
        }

        private void itemSelector_SelectionChanged(object sender, EventArgs e)
        {
            this.OnSelectionChanged(localizationUpdateMode: false);
        }

        #endregion

        #region ViewModel Properties

        private const string propLabelText = "LabelText";

        public string LabelText
        {
            get { return this.DisplayName; }
            set { this.DisplayName = value; }
        }

        public override string DisplayName
        {
            get
            {
                return base.DisplayName;
            }
            protected set
            {
                if (base.DisplayName != value)
                {
                    base.DisplayName = value;
                    this.OnPropertyChanged(propLabelText);
                }
            }
        }

        private string hardwareName;

        private const string propHardwareName = "HardwareName";

        public string HardwareName
        {
            get { return this.hardwareName; }
            set
            {
                this.SetProperty(
                    ref this.hardwareName,
                    value,
                    propHardwareName);
            }
        }

        private string hardwareDescription;

        private const string propHardwareDescription = "HardwareDescription";

        public string HardwareDescription
        {
            get { return this.hardwareDescription; }
            set
            {
                this.SetProperty(
                    ref this.hardwareDescription,
                    value,
                    propHardwareDescription);
            }
        }

        private int hardwareNameMinWidth;   // = 0

        private const string propHardwareNameMinWidth = "HardwareNameMinWidth";

        public int HardwareNameMinWidth
        {
            get { return this.hardwareNameMinWidth; }
            set
            {
                this.SetProperty(
                    ref this.hardwareNameMinWidth,
                    value,
                    propHardwareNameMinWidth);
            }
        }

        #endregion

        #region HardwareSelectionChanged Event

        public event EventHandler HardwareSelectionChanged;

        protected virtual void OnHardwareSelectionChanged()
        {
            this.OnEvent(this.HardwareSelectionChanged);
        }

        #endregion

        #region ItemSelector Properties

        public bool IsEnabled
        {
            get { return !this.itemSelector.IsReadOnly; }
            set { this.itemSelector.IsReadOnly = !value; }
        }

        public int SelectedHardwareIndex
        {
            get { return this.itemSelector.SelectedIndex; }
            set { this.itemSelector.SelectedIndex = value; }
        }

        public IHardwareSettingViewModel SelectedHardware
        {
            get { return this.itemSelector.SelectedItem; }
            set { this.itemSelector.SelectedItem = value; }
        }

        public ObservableCollection<IHardwareSettingViewModel> HardwareItems
        {
            get { return this.itemSelector.Items; }
            set { this.itemSelector.Items = value; }
        }

        #endregion

        #region Public Methods

        public void SortHardwareItems()
        {
            if (this.HardwareItems.Count > 0)
            {
                IHardwareSettingViewModel selectedHardware = this.SelectedHardware;
                bool isReadOnly = this.itemSelector.IsReadOnly;
                this.itemSelector.IsReadOnly = false;
                try
                {
                    this.HardwareItems = new ObservableCollection<IHardwareSettingViewModel>(
                        this.HardwareItems.OrderBy(item => item.Name));
                    if (selectedHardware != null)
                    {
                        this.SelectedHardware = selectedHardware;
                    }
                }
                finally
                {
                    this.itemSelector.IsReadOnly = isReadOnly;
                }
            }
        }

        #endregion

        #region ILocalizable Members

        public void UpdateLocalization()
        {
            this.SortHardwareItems();
            this.OnSelectionChanged(localizationUpdateMode: true);
        }

        #endregion
    }
}
